#include "TestCalendarModel.h"
#include <QDebug>
#include "SqlInterface.h"

namespace QTest
{
template<> char *toString(const Event &event)
{
    QString out = "Event: name(" + event.name() + "), "
            + "begin(" + event.begin().toString("yyyy-MM-dd") + "), "
            + "end(" + event.end().toString("yyyy-MM-dd") + "), "
            + "definition(" + event.definition() + ")";
    return qstrdup(qPrintable(out));
}
}

void TestCalendarModel::initTestCase()
{
    SqlInterface::addConnectDBMemory();
    SqlInterface::createDB();
}

void TestCalendarModel::columnForDayOfWeek()
{
    QDate checkedDate(2011, 3, 1);
    int column = 0;
    int day = 0;
    CalendarModel model;
    model.showMonth(checkedDate.year(), checkedDate.month());
    model.setFirstColumnDay(Qt::Sunday);
    column = model.columnForFirstOfMonth(checkedDate);
    day = model.index(model.firstRow(), column).data(CalendarModel::DATE).toDate().day();
    QVERIFY2(column == 3, qPrintable("Sunday. Wrong column '" + QString::number(column) + "' for first of month"));
    QVERIFY2(day == 1, qPrintable("Sunday. Wrong first day of month '" + QString::number(day) + "'"));

    model.setFirstColumnDay(Qt::Monday);
    column = model.columnForFirstOfMonth(checkedDate);
    day = model.index(model.firstRow(), column).data(CalendarModel::DATE).toDate().day();
    QVERIFY2(column == 2, qPrintable("Monday. Wrong column '" + QString::number(column) + "' for first of month"));
    QVERIFY2(day == 1, qPrintable("Monday. Wrong first day of month '" + QString::number(day) + "'"));

    model.setFirstColumnDay(Qt::Tuesday);
    column = model.columnForFirstOfMonth(checkedDate);
    day = model.index(model.firstRow(), column).data(CalendarModel::DATE).toDate().day();
    QVERIFY2(column == 1, qPrintable("Tuesday. Wrong column '" + QString::number(column) + "' for first of month"));
    QVERIFY2(day == 1, qPrintable("Tuesday. Wrong first day of month '" + QString::number(day) + "'"));

    model.setFirstColumnDay(Qt::Wednesday);
    column = model.columnForFirstOfMonth(checkedDate);
    QVERIFY2(column == 0, qPrintable("Wednesday. Wrong column '" + QString::number(column) + "' for first of month"));

    model.setFirstColumnDay(Qt::Thursday);
    column = model.columnForFirstOfMonth(checkedDate);
    day = model.index(model.firstRow(), column).data(CalendarModel::DATE).toDate().day();
    QVERIFY2(column == 6, qPrintable("Thursday. Wrong column '" + QString::number(column) + "' for first of month"));
    QVERIFY2(day == 1, qPrintable("Thursday. Wrong first day of month '" + QString::number(day) + "'"));

    model.setFirstColumnDay(Qt::Friday);
    column = model.columnForFirstOfMonth(checkedDate);
    day = model.index(model.firstRow(), column).data(CalendarModel::DATE).toDate().day();
    QVERIFY2(column == 5, qPrintable("Friday. Wrong column '" + QString::number(column) + "' for first of month"));
    QVERIFY2(day == 1, qPrintable("Friday. Wrong first day of month '" + QString::number(day) + "'"));

    model.setFirstColumnDay(Qt::Saturday);
    column = model.columnForFirstOfMonth(checkedDate);
    day = model.index(model.firstRow(), column).data(CalendarModel::DATE).toDate().day();
    QVERIFY2(column == 4, qPrintable("Saturday. Wrong column '" + QString::number(column) + "' for first of month"));
    QVERIFY2(day == 1, qPrintable("Saturday. Wrong first day of month '" + QString::number(day) + "'"));
}

void TestCalendarModel::showMonth()
{
    QDate checkedDate(2011, 3, 1);
    CalendarModel model;
    model.showMonth(checkedDate.year(), checkedDate.month());

    int correctDay = 1;
    if (checkedDate.dayOfWeek() != Qt::Monday) {
        checkedDate = checkedDate.addDays(-1);
        correctDay = checkedDate.day();
        checkedDate.setDate(checkedDate.year(), checkedDate.month(), 1);
    }

    for (int i = model.firstRow(); i < model.rowCount(); ++i) {
        for (int j = model.firstColumn(); j < model.columnCount(); ++j, ++correctDay) {
            int modelDay = model.index(i, j).data(CalendarModel::DATE).toDate().day();
            if (correctDay > checkedDate.daysInMonth()) {
                checkedDate = checkedDate.addMonths(1);
                correctDay = 1;
            }
            QCOMPARE(modelDay, correctDay);
        }
    }
}

void TestCalendarModel::updateMonthSchedule()
{
    QSqlQuery query;
    QString currentYear = QDate::currentDate().toString("yyyy");

    query.exec("INSERT INTO Event VALUES(null, "
               "'YYYYMMDD', "
               "'" + currentYear + "0101', "
               "'event 1', "
               "'event 1 text', "
               "'picture')");
    query.exec("INSERT INTO Event VALUES(null, "
               "'RRRRMMDD', "
               "'19870105', "
               "'event 2', "
               "'event 2 text', "
               "'picture')");
    query.exec("INSERT INTO Event VALUES(null, "
               "'YYYYMMDDhhmm', "
               "'" + currentYear + "01061230', "
               "'event 3', "
               "'event 3 text', "
               "'picture')");
    query.exec("INSERT INTO Event VALUES(null, "
               "'MMDD', "
               "'0105', "
               "'event 4', "
               "'event 4 text', "
               "'picture')");
    query.exec("INSERT INTO Event VALUES(null, "
               "'NNN', "
               "'025', "
               "'event 5', "
               "'event 5 text', "
               "'picture')");
    query.exec("INSERT INTO Event VALUES(null, "
               "'MMWD', "
               "'0133', "
               "'event 6', "
               "'event 6 text', "
               "'picture')");

    if (query.lastError().isValid()) {
        qDebug() << query.lastError();
    }

    CalendarModel model;
    model.setFirstColumnDay(Qt::Monday);
    QDate shownDate(QDate::currentDate().year(), 1, 1);
    model.showMonth(shownDate.year(), shownDate.month());

    for (int column = model.firstColumn(); column < model.columnCount(); ++column) {
        for (int row = model.firstRow(); row < model.rowCount(); ++row) {
            QVariant data = model.index(row, column).data(CalendarModel::EVENT);
            if (!data.isValid()) {
                continue;
            }
            EventList_t eventList = data.value<EventList_t>();
            if (eventList.empty()) {
                continue;
            }
            int day = model.index(row, column).data(CalendarModel::DATE).toDate().day();
            switch (day) {
                case 1: {
                    Event event(EventString(currentYear + "0101", "YYYYMMDD"));
                    event.setName("event 1");
                    event.setDefinition("event 1 text");
                    QCOMPARE(eventList.at(0), event);
                }
                break;
                case 5: {
                    Event event1(EventString("19870105", "RRRRMMDD"));
                    event1.setName("event 2");
                    event1.setDefinition("event 2 text");
                    QCOMPARE(eventList.at(0), event1);
                    Event event2(EventString("0105", "MMDD"));
                    event2.setName("event 4");
                    event2.setDefinition("event 4 text");
                    QCOMPARE(eventList.at(1), event2);
                }
                break;
                case 6: {
                    Event event(EventString(currentYear + "01061230", "YYYYMMDDhhmm"));
                    event.setName("event 3");
                    event.setDefinition("event 3 text");
                    QCOMPARE(eventList.at(0), event);
                }
                break;
                case 12: {
                    Event event(EventString("0133", "MMWD"));
                    event.setName("event 6");
                    event.setDefinition("event 6 text");
                    QCOMPARE(eventList.at(0), event);
                }
                break;
                case 25: {
                    Event event(EventString("025", "NNN"));
                    event.setName("event 5");
                    event.setDefinition("event 5 text");
                    QCOMPARE(eventList.at(0), event);
                }
                break;
            }
        }
    }
}
